package net.pws.common.security.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.pws.common.security.PrincipalManagerFactory;
import net.pws.common.security.spi.Principal;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;


public class OpenAuthPageAccessProcessor extends AbstractAuthenticateFilter implements
                                                                       Filter {
    
    public static final Log logger = LogFactory.getLog(LogoutProcessor.class);
    
    private String tokenName = "EPMS_SSO_TOKEN";
    
    private String tokenValue = "4028805137e33ac80137e9d4e7bf000c";
    
    private String protectedUrl = "/biz/open";
    
    public void setTokenName(String tokenName) {
        this.tokenName = tokenName;
    }
    
    public void setTokenValue(String tokenValue) {
        this.tokenValue = tokenValue;
    }
    
    public void setProtectedUrl(String protectedUrl) {
        this.protectedUrl = protectedUrl;
    }
    
    public void doFilter(ServletRequest request,
                         ServletResponse response,
                         FilterChain chain) throws IOException,
                                           ServletException {
        if (!(request instanceof HttpServletRequest)) {
            throw new ServletException("Can only process HttpServletRequest");
        }
        
        if (!(response instanceof HttpServletResponse)) {
            throw new ServletException("Can only process HttpServletResponse");
        }
        
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpServletResponse httpResponse = (HttpServletResponse) response;
        
        if (!required(httpRequest, httpResponse)) {
            chain.doFilter(request, response);
            return;
        }
        
        //the user who has the permission to access the system 
        // can access the demo page.
        String authToken = determineAuthTokenValue(httpRequest);
        if (StringUtils.isNotEmpty(authToken)) {
            Principal principal = PrincipalManagerFactory.getInstance()
                                                         .get(authToken);
            // The princpal is timeout and removed from the cache
            if (principal != null) {
                SecurityFilterProxy.getImplementation(chain).forceEnd(httpRequest,
                                                                      httpResponse);
                return;
            }
        }
        
        String token = determineAuthTokenValueByCookie(httpRequest, tokenName);
        
        if (tokenValue.equals(token)) {
            logger.debug("SSO From EPMS ,excepted token name:" + tokenName
                         + " ,received token value:"
                         + token);
            SecurityFilterProxy.getImplementation(chain).forceEnd(httpRequest,
                                                                  httpResponse);
            return;
        }
        
        if (logger.isDebugEnabled()) {
            logger.debug("No SSO token found, redirecting to " + getLoginPage());
        }
        
        sendRedirect(httpRequest, httpResponse, getLoginPage());
    }
    
    public void removeTokenCookie(HttpServletResponse response) {
        response.addCookie(new Cookie(AUTH_TOKEN_KEY, null));
    }
    
    protected boolean required(HttpServletRequest request,
                               HttpServletResponse response) {
        return matchStart(request, response, protectedUrl);
    }
    
}
